package top.iflyoung.cim.biz.facade;

import lombok.Getter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import top.iflyoung.cim.biz.entity.*;
import top.iflyoung.cim.biz.service.*;
import top.iflyoung.cim.common.enums.StatusEnum;
import top.iflyoung.cim.common.facade.BaseChatFacade;
import top.iflyoung.cim.common.pojo.CIMUserInfo;
import top.iflyoung.cim.common.pojo.RouteInfo;
import top.iflyoung.cim.common.req.GroupMessageVo;
import top.iflyoung.cim.common.req.P2PMessageVo;
import top.iflyoung.cim.common.util.VerifyUtil;

import javax.annotation.PostConstruct;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * @author liguiyang
 * @description 门面模式
 * @sine 1.8
 * @date 2021/9/222:48
 **/
@Getter
@Component("sqlChatFacadeService")
public class SqlChatFacadeService implements BaseChatFacade {
    /**
     * 用户信息
     */
    @Autowired
    private UserService userService;
    /**
     * 点对点Service
     */
    @Autowired
    private P2PChatMessageService p2PChatMessageService;
    /**
     * 分组聊天记录
     */
    @Autowired
    private GroupChatMessageService groupChatMessageService;
    /**
     * 聊天组业务类
     */
    @Autowired
    private ChatGroupService chatGroupService;
    /**
     * 聊天组成员
     */
    @Autowired
    private ChatGroupMemberService chatGroupMemberService;
    /**
     * 好友记录
     */
    @Autowired
    private ChatFriendshipService chatFriendshipService;
    /**
     * 登录记录
     */
    @Autowired
    private ChatLoginStatusService chatLoginStatusService;
    /**
     * 路由信息
     */
    @Autowired
    private ChatRouteInfoService chatRouteInfoService;

    @PostConstruct
    public void init() {

    }

    @Override
    public CIMUserInfo register(String username) {
        if (VerifyUtil.isEmpty(username)) {
            throw new NullPointerException("用户名不能为空");
        }
        return register(new CIMUserInfo(username));
    }

    @Override
    public CIMUserInfo register(CIMUserInfo userInfo) {
        if (VerifyUtil.isEmpty(userInfo)) {
            throw new NullPointerException("用户信息不能为空");
        }
        User user = userService.addUser(new User(userInfo.getUserName()));
        userInfo.setUserId(user.getId());
        return userInfo;
    }

    @Override
    public StatusEnum login(CIMUserInfo userInfo) {
        if (VerifyUtil.isEmpty(userInfo)) {
            throw new NullPointerException("登录的用户为空");
        }
        return chatLoginStatusService.login(userInfo.getUserId()) ? StatusEnum.SUCCESS : StatusEnum.ACCOUNT_NOT_MATCH;
    }

    @Override
    public boolean offline(CIMUserInfo userInfo) {
        if (VerifyUtil.isEmpty(userInfo)) {
            throw new NullPointerException("下线的用户为空");
        }
        return chatLoginStatusService.offline(userInfo.getUserId());
    }

    @Override
    public boolean saveChatRouteInfo(CIMUserInfo userInfo, RouteInfo routeInfo) {
        ChatRouteInfo info = new ChatRouteInfo();
        info.setUserId(userInfo.getUserId());
        info.setIp(routeInfo.getIp());
        info.setServerPort(routeInfo.getHttpPort().longValue());
        info.setChatPort(routeInfo.getCimServerPort().longValue());
        return chatRouteInfoService.save(info);
    }

    @Override
    public Set<String> getMembersByGroupId(Long groupId) {
        List<ChatGroupMember> members = chatGroupMemberService.findMembers(groupId);
        Set<String> memberIds = new HashSet<>();
        if (!VerifyUtil.isEmpty(members)) {
            for (ChatGroupMember member : members) {
                memberIds.add(member.getMemberId().toString());
            }
        }
        return memberIds;
    }

    @Override
    public RouteInfo getUserRouteInfo(Long userId) {
        List<ChatRouteInfo> routeInfos = chatRouteInfoService.findByUserId(userId);
        if (VerifyUtil.isEmpty(routeInfos)) {
            throw new NullPointerException("用户可能没有上线");
        }
        ChatRouteInfo info = routeInfos.get(0);
        return new RouteInfo(info.getIp(), info.getChatPort().intValue(), info.getServerPort().intValue());
    }

    @Override
    public CIMUserInfo getUserInfo(Long userId) {
        User user = userService.getById(userId);
        if (VerifyUtil.isEmpty(user)) {
            throw new NullPointerException("系统不存在这个用户");
        }
        return new CIMUserInfo(user.getId(), user.getName());
    }

    @Override
    public Set<String> getOnlineUserIds() {
        List<User> onlineUsers = userService.findOnlineUsers();
        Set<String> userIds = new HashSet<>();
        if (!VerifyUtil.isEmpty(onlineUsers)) {
            for (User user : onlineUsers) {
                userIds.add(user.getId().toString());
            }
        }
        return userIds;
    }

    @Override
    public boolean saveAndCheckUserLoginStatus(Long userId) {
        //同时在线超过一次，说明是重复登录
        return chatLoginStatusService.getSelfOnlineSize(userId) <= 1;
    }

    @Override
    public boolean saveP2PMessage(P2PMessageVo messageVo) {
        return p2PChatMessageService.save(parseFromP2PMessageVO(messageVo));
    }

    @Override
    public boolean saveGroupMessage(GroupMessageVo messageVo) {
        return groupChatMessageService.save(parseFromGroupMessageVO(messageVo));
    }

    public boolean saveP2PMessages(List<P2PMessageVo> messages) {
        List<P2PChatMessage> messageList = new ArrayList<>();
        if (!VerifyUtil.isEmpty(messageList)) {
            for (P2PMessageVo vo : messages) {
                messageList.add(parseFromP2PMessageVO(vo));
            }
        }
        return p2PChatMessageService.saveBatch(messageList);
    }

    public boolean saveGroupMessages(List<GroupMessageVo> messages) {
        List<GroupChatMessage> messageList = new ArrayList<>();
        if (!VerifyUtil.isEmpty(messageList)) {
            for (GroupMessageVo vo : messages) {
                messageList.add(parseFromGroupMessageVO(vo));
            }
        }
        return groupChatMessageService.saveBatch(messageList);
    }

    public static GroupChatMessage parseFromGroupMessageVO(GroupMessageVo messageVo) {
        GroupChatMessage groupMessage = new GroupChatMessage();
        groupMessage.setMessage(messageVo.getMessage());
        groupMessage.setMessageType(messageVo.getMessageType());
        groupMessage.setGroupId(messageVo.getGroupId());
        groupMessage.setSenderId(messageVo.getSenderId());
        return groupMessage;
    }

    public static P2PChatMessage parseFromP2PMessageVO(P2PMessageVo messageVo) {
        P2PChatMessage p2pMessage = new P2PChatMessage();
        p2pMessage.setMessage(messageVo.getMessage());
        p2pMessage.setMessageType(messageVo.getMessageType());
        p2pMessage.setSenderId(messageVo.getSenderId());
        p2pMessage.setReceiverId(messageVo.getRecevierId());
        return p2pMessage;
    }
}
